/**
 * 
 */
package com.dalonedrau.jogl.opengl.sprite;

import java.awt.Insets;

import com.dalonedrau.jogl.engine.GlobalConsts;
import com.dalonedrau.vectors.Vector3;

/**
 * @author Donald
 */
public abstract class SpriteBaseImpl implements SpriteBase {
	/** the unmodified value of the alpha color channel. */
	private float	alpha			= 1;
	/** the unmodified value of the blue color channel. */
	private float	blue			= 1;
	/** flag for displaying debuging output. */
	private boolean	debug			= false;
	/** all flags assigned. */
	private long	flags;
	/** the number of values in the storage array for rendering values. */
	private int		floatStoreNum	= 0;
	/** the full value of the alpha color channel, including modifications. */
	private float	fullAlpha;
	/** the full value of the blue color channel, including modifications. */
	private float	fullBlue;
	/** the full value of the green color channel, including modifications. */
	private float	fullGreen;
	/** the full value of the red color channel, including modifications. */
	private float	fullRed;
	/** the unmodified value of the green color channel. */
	private float	green			= 1;
	/** the value of all modifications applied to the alpha color channel. */
	private float	modAlpha;
	/** the value of all modifications applied to the blue color channel. */
	private float	modBlue;
	/** the value of all modifications applied to the green color channel. */
	private float	modGreen;
	/** the value of all modifications applied to the red color channel. */
	private float	modRed;
	/** the time the sprite's move started. */
	private long	moveStart;
	/**
	 * the length of time the sprite's move lasts. At the end of the time, the
	 * sprite is moved based on its direction and velocity.
	 */
	private long	moveTimer;
	/** the parent container. */
	private int		parentRefId		= -1;
	private Insets	partialInsets	= new Insets(0, 0, 0, 0);
	/** the unmodified value of the red color channel. */
	private float	red				= 1;
	private float	scaleFactorHeight;
	private float	scaleFactorWidth;
	/** the velocity. */
	private Vector3	velocity;
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void assignFlag(final long flag) {
		flags |= flag;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void clearFlags() {
		flags = 0;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void clearFloatStore() {
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getAlpha() {
		return alpha;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getBlue() {
		return blue;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getFloatStoreNumber() {
		return floatStoreNum;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getFullAlpha() {
		return fullAlpha;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getFullBlue() {
		return fullBlue;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getFullGreen() {
		return fullGreen;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getFullRed() {
		return fullRed;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getGreen() {
		return green;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getModAlpha() {
		return modAlpha;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getModBlue() {
		return modBlue;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getModGreen() {
		return modGreen;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getModRed() {
		return modRed;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public long getMoveDuration() {
		return moveTimer;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public long getMoveStart() {
		return moveStart;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int getParentRefId() {
		return parentRefId;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final Insets getPartialOffsets() {
		return partialInsets;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getRed() {
		return red;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getScaleFactorHeight() {
		return scaleFactorHeight;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getScaleFactorWidth() {
		return scaleFactorWidth;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public Vector3 getVelocity() {
		return velocity;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final boolean hasFlag(final long flag) {
		return (flags & flag) == flag;
	}
	/**
	 * Gets the debugging output flag.
	 * @return <code>boolean</code>
	 */
	@Override
	public final boolean isDebug() {
		return debug;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeFlag(final long flag) {
		flags &= ~flag;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setAlpha(final float a) {
		alpha = a;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setBlue(final float b) {
		blue = b;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setColor(final float[] color) throws Exception {
		if (color.length < GlobalConsts.INT_003
				|| color.length > GlobalConsts.INT_004) {
			throw new Exception("Invalid color array.");
		}
		red = color[0];
		green = color[1];
		blue = color[2];
		if (color.length == GlobalConsts.INT_004) {
			alpha = color[GlobalConsts.INT_003];
		}
		floatStoreNum = 0;
	}
	/**
	 * Sets the debugging output flag.
	 * @param val the flag to set
	 */
	@Override
	public final void setDebug(boolean val) {
		debug = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFloatStoreNumber(final int val) {
		floatStoreNum = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setFullAlpha(final float a) {
		fullAlpha = a;
		if (fullAlpha > 1f) {
			fullAlpha = 1f;
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setFullBlue(final float b) {
		fullBlue = b;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setFullGreen(final float g) {
		fullGreen = g;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setFullRed(final float r) {
		fullRed = r;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setGreen(final float g) {
		green = g;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setModAlpha(final float a) {
		modAlpha = a;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setModBlue(final float b) {
		modBlue = b;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setModGreen(final float g) {
		modGreen = g;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setModRed(final float r) {
		modRed = r;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setMoveStart(final long time) {
		moveStart = time;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setMoveTimer(final long time) {
		moveTimer = time;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setParentRefId(final int val) {
		parentRefId = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setRed(final float r) {
		red = r;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setScaleFactorHeight(final float val) {
		scaleFactorHeight = val;
		if (scaleFactorHeight < 0) {
			scaleFactorHeight = 0;
		}
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setScaleFactorWidth(final float val) {
		scaleFactorWidth = val;
		if (scaleFactorWidth < 0) {
			scaleFactorWidth = 0;
		}
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setVelocity(final double x, final double y) {
		if (velocity != null) {
			velocity.setX(x);
			velocity.setY(y);
		} else {
			velocity = new Vector3(x, y, 1);
		}
		setFloatStoreNumber(0);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setVelocity(final double x, final double y, final double z) {
		if (velocity != null) {
			velocity.set(x, y, z);
		} else {
			velocity = new Vector3(x, y, z);
		}
		setFloatStoreNumber(0);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setVelocity(final Vector3 v) {
		velocity = v;
		setFloatStoreNumber(0);
	}
}
